from oauth.models import *
from .filters import OauthFilter
from django_filters.rest_framework import DjangoFilterBackend

from rest_framework.generics import GenericAPIView
from rest_framework.mixins import UpdateModelMixin
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework.exceptions import ValidationError
from rest_framework_jwt.views import ObtainJSONWebToken
from rest_framework_jwt.utils import jwt_decode_handler
from api.serializers.oauth import UserProfileserializer,UsersPartialSerializer,ResetPasswordSerializer
from rest_framework.viewsets import ModelViewSet
from utils.Mixins import  MultipleDestroyMixin
from django.contrib.auth import get_user_model
Users = get_user_model()

from rest_framework import status
from django.conf import settings
from django.core.mail import send_mail
from user_agents import parse

from utils.custom_log   import log_start
logger = log_start('account')


def sendMail(to_addr,subject,message):
    print(settings.EMAIL_PASSWORD)
    email_title = subject
    email_body = message
    email_to = to_addr
    send_status = send_mail(subject=email_title, message=email_body,
                            from_email=settings.EMAIL_HOST_USER, recipient_list=[email_to])
    return send_status
    #  sendMail(to_addr='admin@attacker.club',subject="Login",message=email_body)


   


class UserLoginView(ObtainJSONWebToken):
    """
    post:
    用户登录

    用户登录, status: 200(成功), return: Token信息
    """

    def post(self, request, *args, **kwargs):
        if 'HTTP_X_FORWARDED_FOR' in request.META.keys():
            ip =  request.META['HTTP_X_FORWARDED_FOR']
        else:
            ip = request.META['REMOTE_ADDR']
        user_ua = request.META['HTTP_USER_AGENT']
        user_agent=parse(user_ua)
        ua = "{0} {1}".format(user_agent.browser.family,user_agent.browser.version_string)
        pc = "{0} {1}".format(user_agent.os.family,user_agent.os.version_string)
        username = request.data.get('username')
        info = "[{0}]用户登录 {1} {2} ip地址:{3}".format(username,pc,ua,ip)
        logger.info(info)

        # json: request.data
        # 表单: request.POST.get('username')
        # sendMail(to_addr='admin@attacker.club',subject="CMDB 登录通知",message=info)

        # 重写父类方法, 定义响应字段内容
        response = super().post(request, *args, **kwargs)
        if response.status_code == 200:
            # conn = get_redis_connection('user_info')
            # conn.incr('visits')
            
            return response
        else:
            if response.data.get('non_field_errors'):
                # 日后将增加用户多次登录错误,账户锁定功能(待完善)
                if isinstance(response.data.get('non_field_errors'), list) and len(
                        response.data.get('non_field_errors')) > 0:
                    if response.data.get('non_field_errors')[0].strip() == '无法使用提供的认证信息登录。':
                        return Response(data={'detail': '用户名或密码错误'}, status=status.HTTP_400_BAD_REQUEST)
            raise ValidationError(response.data)


class UserInfoView(APIView):
    """
    get:
    当前用户信息

    当前用户信息,status: 200(成功), return: 用户信息和权限
    """
    def get(self, request):

        token = request.META.get('HTTP_AUTHORIZATION')
        token_user = jwt_decode_handler(token.split()[1])
        user_id = token_user['user_id']  # 获取登陆用户id
        data = Users.objects.get(id=user_id).get_user_info()
        data["avatar"]= request._current_scheme_host + data['avatar']
        return Response(data=data)
        

        

class LogoutAPIView(APIView):
    """
    post:
    退出登录

    退出登录,status: 200 (成功), return: None
    """
    def post(self, request):
        content = {}
        # 后续将增加redis token黑名单功能
        return Response(data=content)





class UsersViewSet(ModelViewSet,MultipleDestroyMixin):
    """
    create:
    用户--新增

    用户新增, status: 201(成功), return: 新增用户信息

    destroy:
    用户--删除

    用户删除, status: 204(成功), return: None

    multiple_delete:
    用户--批量删除

    用户批量删除, status: 204(成功), return: None

    update:
    用户--修改

    用户修改, status: 200(成功), return: 修改后的用户信息

    partial_update:
    用户--局部修改

    用户局部修改(激活/锁定), status: 200(成功), return: 修改后的用户信息

    list:
    用户--获取列表

    用户列表信息, status: 200(成功), return: 用户信息列表

    retrieve:
    用户--详情
    
    用户详情信息, status: 200(成功), return: 单个用户信息详情
    """
    
    queryset = UserProfile.objects.all()
    serializer_class = UserProfileserializer
    filter_backends = [DjangoFilterBackend]
    filter_class = OauthFilter

    def get_serializer_class(self):
        if self.action == 'partial_update':
            return UsersPartialSerializer
        else:
            return UserProfileserializer

class PermissionsAPIView(APIView):
    """
    get:
    获取用户拥有权限ID列表

    获取用户拥有权限ID列表, status: 200(成功), return: 用户拥有权限ID列表
    """
    def get(self, request, pk):
        try:
            user = Users.objects.get(id=pk)
        except Users.DoesNotExist:
            raise ValidationError('无效的用户ID')
        # admin角色
        if 'admin' in user.roles.values_list('name', flat=True) or user.is_superuser:
            return Response(data={'results': Permissions.objects.values_list('id', flat=True)})
        # 其他角色
        return Response(data={'results': list(filter(None, set(user.roles.values_list('permissions__id', flat=True))))})



class ResetPasswordAPIView(UpdateModelMixin, GenericAPIView):
    """
    patch:
    用户--重置密码

    用户重置密码, status: 200(成功), return: None
    """
    queryset = Users.objects.all()
    serializer_class = ResetPasswordSerializer

    def patch(self, request, *args, **kwargs):
        return self.partial_update(request, *args, **kwargs)